﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataSource;

namespace Strategy.Linkage
{
    public class T0Univ
    {
        TimeSpan tmSpan; //保留多久历史信息
        Dictionary<string, List<Level2Struct>> dataSet;
        DateTime currTime; //当前时间
        public T0Univ(TimeSpan snapTimeSpan)
        {
            tmSpan = snapTimeSpan;
            dataSet = new Dictionary<string, List<Level2Struct>>();
        }

        public void TimeSync(DateTime dt)
        {
            currTime = dt;
        }

        private DateTime GetCurrentTime()
        {
            return currTime;
        }

        public void Add(Level2Struct ls)
        {
            if (!dataSet.ContainsKey(ls.code))
            {
                dataSet[ls.code] = new List<Level2Struct>();
                dataSet[ls.code].Add(ls);
            }
            else //只保留特定时间范围的序列信息
            {
                List<Level2Struct> lls = dataSet[ls.code];
                lls.Add(ls);
                int i = 0;
                for(; i < lls.Count; i++)
                {
                    if (lls[i].time + tmSpan > ls.time) break;//序列i-1（包括）之前的项可以移除
                }
                lls.RemoveRange(0, i);
                dataSet[ls.code] = lls;
            }
        }

        public int CountRisingTimeSpan(string code, float ret_ref, TimeSpan tm_win) //计算目前为止上涨ret_ref所花的时间,考察时间段由时间窗口tm_win决定
        {
            if (!dataSet.ContainsKey(code))
            {
                return 0; //还没有接收到行情信息，则ret设为0
            }
            DateTime deadTime = GetCurrentTime() - tm_win;
            List<Level2Struct> lls = dataSet[code];
            int i = lls.Count - 1;
            float cur_px = lls[i].price; 
            float px = 0; //while中不断获取的price
            float ret = 0; //while中不断计算的ret
            bool timeout = false;
            while (i >= 0)
            {
                if (lls[i].time < deadTime)
                {
                    timeout = true;
                    break;
                }
                px = lls[i].price;
                ret = (cur_px - px) / px * 10000;
                if (ret >= ret_ref) break;
                i--;
           
            }
            if (timeout)
            {
                return 0 ;
            }
            else
            {
                return (int)(GetCurrentTime() - lls[i].time).TotalSeconds;
            }

        }

        public float CountMaxRet(string code, TimeSpan span) //计算最近span时间内内最大涨幅
        {
            if (!dataSet.ContainsKey(code))
            {
                return 0; //还没有接收到行情信息，则ret设为0
            }
            DateTime deadTime = GetCurrentTime() - span;
            List<Level2Struct> lls = dataSet[code];
            int i = lls.Count-1;
            float maxPx = 1; //随便设置的初始值
            float minPx = 1;
            while (i >= 0)
            {
                if(i == lls.Count - 1)
                {
                    maxPx = lls[i].price;
                    minPx = maxPx;
                }
                else
                {
                    if (lls[i].time < deadTime) break;
                    if (lls[i].price > maxPx)
                    {
                        maxPx = lls[i].price;
                        minPx = lls[i].price;
                    }
                    else if (lls[i].price < minPx)
                    {
                        minPx = lls[i].price;
                    }
                }
                i--; 
            }
            return minPx>0 ? (maxPx - minPx) / minPx *10000 : 0;
        }


        public float CountCurRet(string code, DateTime dt) //计算 dt开始到现在的ret
        {
            if (!dataSet.ContainsKey(code))
            {
                return 0; //还没有接收到行情信息，则ret设为0
            }
            List<Level2Struct> lls = dataSet[code];
            if(lls[lls.Count-1].time <= dt) // 如果没有最新的行情，返回0
            {
                return 0;
            }
            float newPx = lls[lls.Count - 1].price;
            int i = 0;
            while(lls[i].time <= dt)
            {
                i++;
            }
            float dtPx;
            if (i > 0)
            {
                dtPx = lls[i - 1].price;//dt时刻的price
            }
            else
            {
                dtPx = 0;
            }
            
            return dtPx>0 ? (newPx - dtPx) / dtPx * 10000 : 0;
        }

        public float CountMinRet(string code,TimeSpan span) //计算最近span时间内最大跌幅
        {
            DateTime deadTime = GetCurrentTime() - span;
            List<Level2Struct> lls = dataSet[code];
            int i = lls.Count - 1;
            float maxPx = 1;
            float minPx = 1;
            while (i >= 0)
            {
                if (i == lls.Count - 1)
                {
                    maxPx = lls[i].price;
                    minPx = maxPx;
                }
                else
                {
                    if (lls[i].time < deadTime) break;
                    if (lls[i].price > maxPx)
                    {
                        maxPx = lls[i].price;
                       
                    }
                    else if (lls[i].price < minPx)
                    {
                        minPx = lls[i].price;
                        minPx = lls[i].price;
                    }
                }
                i--;
            }
            return maxPx>0 ? -(maxPx - minPx) / maxPx * 10000 : 0;
        }

        public double CountVolume(string code,  DateTime dt)
        {
            if (!dataSet.ContainsKey(code))
            {
                return 0; //还没有接收到行情信息，则ret设为0
            }
            List<Level2Struct> lls = dataSet[code];
            if (lls[lls.Count - 1].time <= dt) // 如果没有最新的行情，返回0
            {
                return 0;
            }
            double newVol = lls[lls.Count - 1].amount;
            int i = 0;
            while (lls[i].time <= dt)
            {
                i++;
            }
            double dtVol;
            if (i > 0)
            {
                dtVol = lls[i - 1].amount;//dt时刻的price
            }
            else
            {
                dtVol = 0;
            }

            return dtVol > 0 ? (newVol - dtVol) : 0;
        }

        public double CountBalance(string code, DateTime dt)
        {
            if (!dataSet.ContainsKey(code))
            {
                return 0; //还没有接收到行情信息，则ret设为0
            }
            List<Level2Struct> lls = dataSet[code];
            if (lls[lls.Count - 1].time <= dt) // 如果没有最新的行情，返回0
            {
                return 0;
            }
            double newBl = lls[lls.Count - 1].balance;
            int i = 0;
            while (lls[i].time < dt)
            {
                i++;
            }
            double dtBl;
            if (i > 0)
            {
                dtBl = lls[i - 1].balance;//dt时刻的成交额
            }
            else
            {
                dtBl = 0;
            }

            return dtBl > 0 ? (newBl - dtBl) : 0;
        }

    }

}
